#pragma once

#pragma pack(push, 8)
#include <memory>
#include <vector>
#include <variant>
#pragma pack(pop)

#include "DriverStateMachine.h"

namespace Driver {

class DriverModel {
public:
    explicit DriverModel(SlavePDOS* pdos);
    ~DriverModel();

public:
    void TimeTick();
    void FaultReset();

    void ShutDown();
    void SwitchOn();
    void DisableOperation();
    void EnableOperation();
    void DisableVoltage();
    void QuickStop();

    bool IsNotReadyToSwitchOn();
    bool IsNormal();
    bool IsFault();
    bool IsFaultReactionActive();

    bool IsSwitchOnDisabled();
    bool IsReadyToSwitchOn();
    bool IsSwitchedOn();
    bool IsOperationEnabled();
    bool IsQuickStopActive();

    bool IsStandStill();
    bool IsMoving();
    bool IsHome();

    bool IsHomeDisable();
    bool IsReadyToHome();
    bool IsHoming();
    bool IsHomeFinished();
    bool IsHomeHalted();
    bool IsSwitchToHomeError();
    bool IsHomeErrored();

    void PowerOn();
    void PowerOff();
    void Home();
    void CancelHome();
    void Move();
    void Stop();
    void Faster();
    void Slower();

    void HaltHome();

private:
    DriverData driver_data_;
    sml::sm<TransitionTable> sm_;             // 轴状态机
    std::variant<std::monostate,
        decltype(sml::state<OperationEnabledState>),
        decltype(sml::state<NormalState::SwitchOnDisabledState>)
    > target_state_{};

private:
    void SwitchToTargetState();
};

}  //  namespace driver